package com.uwlaser.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.uwlaser.base.CommonTree;
import com.uwlaser.domain.ProductModelLien;
import com.uwlaser.domain.ProductType;
import com.uwlaser.service.CraftParamDetailService;
import com.uwlaser.service.CraftParamService;
import com.uwlaser.service.ProductModelLienService;
import com.uwlaser.service.dto.CraftParamDetailDto;
import com.uwlaser.service.dto.CraftParamDto;
import com.uwlaser.service.mapper.ProductTypeMapper;
import lombok.AllArgsConstructor;
import com.uwlaser.base.PageInfo;
import com.uwlaser.base.QueryHelpMybatisPlus;
import com.uwlaser.base.impl.CommonServiceImpl;
import com.uwlaser.utils.ConvertUtil;
import com.uwlaser.utils.PageUtil;
import com.uwlaser.domain.ProductModel;
import com.uwlaser.service.ProductModelService;
import com.uwlaser.service.dto.ProductModelDto;
import com.uwlaser.service.dto.ProductModelQueryParam;
import com.uwlaser.service.mapper.ProductModelMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
// 默认不使用缓存
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;
import java.util.*;

/**
* @author zk-Qin
* @date 2022-05-11
*/
@Service
@AllArgsConstructor
// @CacheConfig(cacheNames = ProductModelService.CACHE_KEY)
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class ProductModelServiceImpl extends CommonServiceImpl<ProductModelMapper, ProductModel> implements ProductModelService {

    // private final RedisUtils redisUtils;
    private final ProductModelMapper productModelMapper;

    private final ProductTypeMapper productTypeMapper;

    private final ProductModelLienService productModelLienService;

    private final CraftParamService craftParamService;

    private final CraftParamDetailService craftParamDetailService;

    @Override
    public PageInfo<ProductModelDto> queryAll(ProductModelQueryParam query, Pageable pageable) {
        IPage<ProductModel> queryPage = PageUtil.toMybatisPage(pageable);
        IPage<ProductModel> page = productModelMapper.selectPage(queryPage, QueryHelpMybatisPlus.getPredicate(query));
        List<ProductModelDto> productModelDtoList = ConvertUtil.convertList(page.getRecords(),ProductModelDto.class);
        productModelDtoList.forEach(productModel -> {
            CraftParamDto craftParamDto = craftParamService.getCraftParamId(productModel.getProductCode());
            if(craftParamDto != null){
                Set<CraftParamDetailDto> craftParamDetailDtoList = craftParamDetailService.getParamDetail(craftParamDto.getId());
                productModel.setCraftParamDetails(craftParamDetailDtoList);
            }
        });
        return new PageInfo<>(page.getTotal(), productModelDtoList);
    }

    @Override
    public List<ProductModelDto> queryAll(ProductModelQueryParam query){
        return ConvertUtil.convertList(productModelMapper.selectList(QueryHelpMybatisPlus.getPredicate(query)), ProductModelDto.class);
    }

    @Override
    public ProductModel getById(Integer id) {
        return productModelMapper.selectById(id);
    }

    @Override
    // @Cacheable(key = "'id:' + #p0")
    public ProductModelDto findById(Integer id) {
        return ConvertUtil.convert(getById(id), ProductModelDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(ProductModelDto resources) {
        ProductModel entity = ConvertUtil.convert(resources, ProductModel.class);
        ProductModel productModel = new ProductModel();
        productModel.setProductCode(entity.getProductCode());
        Integer integer = productModelMapper.selectCount(new QueryWrapper<>(productModel));
        if(integer > 0){
            throw new RuntimeException("产品型号【"+productModel.getProductCode()+"】已存在！");
        }

        productModel.setProductCode(null);
        productModel.setMaterialCode(entity.getMaterialCode());

        integer = productModelMapper.selectCount(new QueryWrapper<>(productModel));
        if(integer > 0){
            throw new RuntimeException("关联物料【"+productModel.getMaterialCode()+"】已经和其他产品关联了，不能重复关联！");
        }

        List<ProductModelLien> lines = resources.getProductModelLines();
        if(lines != null && lines.size() != 0){
            productModelLienService.saveBatch(lines);
        }
        return productModelMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateById(ProductModelDto resources){
        ProductModel entity = ConvertUtil.convert(resources, ProductModel.class);
        int ret = productModelMapper.updateById(entity);

        ProductModel productModel = new ProductModel();
        productModel.setProductCode(entity.getProductCode());
        Integer integer = productModelMapper.selectCount(new QueryWrapper<>(productModel));
        if(integer >= 2){
            throw new RuntimeException("产品型号【"+productModel.getProductCode()+"】已存在！");
        }

        productModel.setProductCode(null);
        productModel.setMaterialCode(entity.getMaterialCode());

        integer = productModelMapper.selectCount(new QueryWrapper<>(productModel));
        if(integer >= 2){
            throw new RuntimeException("关联物料【"+productModel.getMaterialCode()+"】已经和其他产品关联了，不能重复关联！");
        }

        ProductModelLien productModelLien = new ProductModelLien();
        productModelLien.setModelCode(entity.getProductCode());
        productModelLienService.remove(new QueryWrapper<>(productModelLien));

        List<ProductModelLien> lines = resources.getProductModelLines();
        if(lines != null && lines.size() != 0){
            productModelLienService.saveBatch(lines);
        }
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByIds(Set<Integer> ids){
        // delCaches(ids);
        //删除关联关系
        for (Integer id : ids) {
            ProductModel productModel = productModelMapper.selectById(id);
            ProductModelLien productModelLien = new ProductModelLien();
            productModelLien.setModelCode(productModel.getProductCode());
            productModelLienService.remove(new QueryWrapper<>(productModelLien));
        }
        return productModelMapper.deleteBatchIds(ids);
    }

    /**
     * 获取产品结构树
     * @return
     */
    @Override
    public List<CommonTree> getTree() {

        LinkedHashMap<String, CommonTree> treeMap = new LinkedHashMap<>();
        //获取产品类型
        List<ProductType> types = productTypeMapper.selectList(new QueryWrapper<ProductType>().orderByDesc("id"));
        if(types == null){
            return new ArrayList<>();
        }
        for (ProductType type : types) {
            CommonTree commonTree = new CommonTree();
            commonTree.setId(type.getId());
            commonTree.setCode(type.getProductType());
            commonTree.setLabel(type.getProductTypeName());
            commonTree.setChildren(new ArrayList<>());
            commonTree.setType("type");
            treeMap.put(type.getProductType(),commonTree);
        }
        //获取产品型号
        List<ProductModel> models = productModelMapper.selectList(null);
        if(models != null){
            for (ProductModel model : models) {
                CommonTree commonTree = treeMap.get(model.getProductType());
                if(commonTree != null){
                    CommonTree childrenTree = new CommonTree();
                    childrenTree.setId(model.getId());
                    childrenTree.setCode(model.getProductCode());
                    childrenTree.setLabel(model.getProductName());
                    childrenTree.setType("model");
                    commonTree.getChildren().add(childrenTree);
                }
            }
        }
        List<CommonTree> resTree = new ArrayList<>();
        for (String key : treeMap.keySet()) {
            resTree.add(treeMap.get(key));
        }
        return resTree;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeById(Integer id){
        Set<Integer> set = new HashSet<>(1);
        set.add(id);
        return this.removeByIds(set);
    }

    /*
    private void delCaches(Integer id) {
        redisUtils.delByKey(CACHE_KEY + "::id:", id);
    }

    private void delCaches(Set<Integer> ids) {
        for (Integer id: ids) {
            delCaches(id);
        }
    }*/

    /*
    @Override
    public void download(List<ProductModelDto> all, HttpServletResponse response) throws IOException {
      List<Map<String, Object>> list = new ArrayList<>();
      for (ProductModelDto productModel : all) {
        Map<String,Object> map = new LinkedHashMap<>();
              map.put("产品型号", productModel.getProductCode());
              map.put("产品名称", productModel.getProductName());
              map.put("产品类型", productModel.getProductType());
              map.put("描述", productModel.getRemark());
              map.put("创建人", productModel.getCreateBy());
              map.put("创建时间", productModel.getCreateTime());
              map.put("更新人", productModel.getUpdateBy());
              map.put("更新时间", productModel.getUpdateTime());
        list.add(map);
      }
      FileUtil.downloadExcel(list, response);
    }*/
}
